package com.lgl.scs.userIndex.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lgl.scsapi.base.dao.DaoSupport;
import com.lgl.scsapi.system.model.AppUser;
import com.lgl.scsapi.system.model.PageData;
import com.lgl.scsapi.system.model.ServiceOrder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * 主页服务订单处理service
 */

@Service("serviceOrderService")
public class ServiceOrderService {
	@Resource(name = "daoSupport")
	private DaoSupport dao;

	/**
	 * 获取服务订单信息列表(前台页面使用)
	 * @param pageNo 当前页号
	 * @param pageSize  每页显示记录数
	 * @param pageData  PageData参数
	 * @return PageInfo对象
	 */
	public PageInfo pageServiceOrder(int pageNo,int pageSize, PageData pageData) {
		PageHelper.startPage(pageNo,pageSize);
		List<PageData> orderList = (List<PageData>) dao.findForList("ServiceOrderMapper.pageServiceOrder", pageData);
		return new PageInfo(orderList);
	}
	/**
	 * 获取我的服务订单信息列表(前台页面使用)
	 * @param pageNo 页码
	 * @param pageSize 每页显示记录数
	 * @param pageData 查询PageData参数
	 * @return PageInfo对象
	 */
	public PageInfo pageMyServiceOrder(int pageNo,int pageSize,PageData pageData) {
		PageHelper.startPage(pageNo,pageSize);
		List<PageData> myOrderList = (List<PageData>) dao.findForList("ServiceOrderMapper.pageMyServiceOrder", pageData);
		return new PageInfo(myOrderList);
	}

	/**
	 * 保存服务订单信息
	 * @param serviceOrder 服务订单对象
	 * @return 成功：true，失败：false
	 */
	public boolean saveServiceOrder(ServiceOrder serviceOrder) {
		int row = dao.save("ServiceOrderMapper.saveServiceOrder", serviceOrder);
		return row > 0;
	}

	/**
	 * 修改服务订单状态
	 * @param pd 查询PageData参数
	 * @return 成功的行数
	 */
	public int editServiceOrderState(PageData pd){
		return dao.update("ServiceOrderMapper.editServiceOrderState", pd);
	}
	/**
	* 通过id获取订单对象ServiceOrder
	* @param pd 查询PageData参数
    * @return ServiceOrder对象
	*/
	public ServiceOrder getServiceOrderById(PageData pd) {
		return (ServiceOrder) dao.findForObject("ServiceOrderMapper.getServiceOrderById", pd);
	}

	/**
	*通过订单号获取数据 
	* @param pd 查询PageData参数
	*/
	public ServiceOrder getServiceOrderByBillNumber(PageData pd) {
		return (ServiceOrder) dao.findForObject("ServiceOrderMapper.getServiceOrderByBillNumber", pd);
	}

	/**
	 * 获取我赚到的总钱数
	 * @param pd 查询PageData参数
	 * @return 赚到的总钱数
	 */
	public String myMakeMoney(PageData pd){
		Object makeMoneyObj = dao.findForObject("ServiceOrderMapper.myMakeMoney", pd);
		return makeMoneyObj == null ? "0" : makeMoneyObj.toString();
	}

	/**
	 * 保存用户评论
	 * @param pd 保存的PageData参数
	 * @param user  当前登录用户
	 * @return 成功/失败标识
	 * @throws Exception 抛出异常
	 */
	@Transactional(value = "scsTxManager",propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ,rollbackFor = Exception.class)
	public String saveUserRate(PageData pd, AppUser user)throws Exception{
		String levelNum = pd.getString("levelNum"),userImpression = pd.getString("userImpression"),billNo = pd.getString("billNo"),
			rateText = pd.getString("rateText"), rateIssueOrRob = pd.getString("rateIssueOrRob");
		StringBuilder urSql = new StringBuilder("SELECT s.so_get_user,s.so_user_id FROM cor_service_order s WHERE s.so_status in (2,3,7) and s.so_bill_number='" + billNo + "'");
		List<PageData> billList = (List<PageData>) dao.findForList("UtilMapper.listDataBySql", urSql);
		if (billList == null || billList.isEmpty()) {
			return "1";
		}
		PageData billPd = billList.get(0);
		String personRated = billPd.getString("so_user_id");
		if ("0".equals(rateIssueOrRob)) {//当前用户是发布人，对服务提供者进行评价
			if (!user.getUserId().equals(billPd.getString("so_user_id"))) {//如果当前登录人不是该单据的发布人
				return "3";
			}
			personRated = billPd.getString("so_get_user");
		}else if ("1".equals(rateIssueOrRob)) {//当前用户是服务提供者，对发布人进行评价
			if (!user.getUserId().equals(billPd.getString("so_get_user"))) {//如果当前登录人不是该单据的抢单人
				return "4";
			}
		}
		String userId = user.getUserId();
		urSql.setLength(0);
		urSql.append("INSERT INTO cor_user_rate(rater,rate_bill_no,person_rated,grade,impress,rate_content) values('").
			append(userId + "','"+billNo+"','"+personRated+"',"+levelNum+",'"+userImpression+"','" + rateText + "')");
		int rows = dao.save("UtilMapper.insertObject", urSql);
		if (rows < 1) {
			return "5";
		}
		urSql.setLength(0);
		//0：未评论；1:发布人、抢单人均已评论；2:发布人已评，抢单人未评；3：抢单人已评，发布人未评
		urSql.append("UPDATE cor_service_order o set o.is_commented=(case when o.so_user_id='"+userId+"' and o.is_commented='0' then '2' ")
			.append("when o.so_user_id='"+userId+"' and o.is_commented='3' then '1' ")
			.append("when o.so_get_user='"+userId+"' and o.is_commented='0' then '3' ")
			.append("when o.so_get_user='"+userId+"' and o.is_commented='2' then '1' else o.is_commented end) where o.so_status in (2,3,7) and o.so_bill_number='"+billNo+"'");
		rows = dao.update("UtilMapper.updateDataBySql", urSql);
		if (rows < 1) {
			throw new Exception("保存用户评论的订单状态失败");
		}
		return "0";
	}
    /**
     * 修改服务订单信息
     * @param robberUserId 抢单人ID
     * @param robberDonePd 抢单参数PageData
     * @return 抢单人完成成功/失败标识
     */
    public String robberDoneOrder(String robberUserId,PageData robberDonePd){
        String checkResult = checkDoneOrder(robberDonePd,"1","1",robberUserId);
        if (StringUtils.hasText(checkResult)){
            robberDonePd.clear();
            return checkResult;
        }
        robberDonePd.put("oldSoStatus", "1");
        robberDonePd.put("soStatus", "4");
        robberDonePd.put("soGetUser", robberUserId);
        int robberDoneRow = dao.update("ServiceOrderMapper.robberDoneOrder", robberDonePd);
        return robberDoneRow < 1 ? "1" : "0";
    }

    /**
     * 验证完成、取消订单等相关内容
     * @param donePd 用于查询订单相关参数
     * @param checkStatus 要检查的状态
     * @param issueOrRob 0：订单发布人操作，1：抢单人操作
     * @param loginUserId 登录用户ID
     * @return 检测成功/失败标识
     */
    private String checkDoneOrder(PageData donePd,String checkStatus,String issueOrRob,String loginUserId){
        ServiceOrder doneOrder = getServiceOrderByBillNumber(donePd);
        if (doneOrder == null){
            return "2";
        }
        //robberDoneOrder方法（抢单人执行完成操作）：如果不是已抢未完成,则不执行完成操作
        //issuerDoneOrder方法（发布人执行完成操作）：如果不是未确认，则不执行完成操作
        if (!checkStatus.equalsIgnoreCase(String.valueOf(doneOrder.getSoStatus()))){
            return "3";
        }
        String orderUserId = "0".equals(issueOrRob) ? doneOrder.getSoUserId() : doneOrder.getSoGetUser();
        //robberDoneOrder方法（抢单人执行完成操作）：如果不是自己抢的,则不执行完成操作
        //issuerDoneOrder方法（发布人执行完成操作）：如果不是自己发布，则不执行完成操作
        if (!orderUserId.equals(loginUserId)){
            return "4";
        }
        return null;
    }
	/**
	 * 取消未抢订单操作
	 * @param cancelUser 取消用户
	 * @param cancelPd 参数，包括单号
	 * @return 0:成功，1：失败
	 */
	public String cancelServiceOrder(AppUser cancelUser,PageData cancelPd){
        String cancelCheckResult = checkDoneOrder(cancelPd,"0","0",cancelUser.getUserId());
        if (StringUtils.hasText(cancelCheckResult)){
            cancelPd.clear();
            return cancelCheckResult;
        }
		//要更新的状态，5：已取消
        cancelPd.put("soStatus","5");
		//where条件中的状态，只有未抢的单才能取消
        cancelPd.put("cancelSoStatus","0");
        cancelPd.put("issuerId", cancelUser.getUserId());
		int cancelRows = dao.update("ServiceOrderMapper.cancelServiceOrder", cancelPd);
        cancelPd.clear();
		return cancelRows > 0 ? "0" : "1";
	}
    /**
     * 取消未抢订单操作
     * @param deleteUser 删除用户
     * @param deletePd 参数，包括单号
     * @return 0:成功，1：失败
     */
    @Transactional(value = "scsTxManager",propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ,rollbackFor = Exception.class)
    public String deleteServiceOrder(AppUser deleteUser,PageData deletePd) throws Exception {
        PageData pdOrder = (PageData) dao.findForObject("ServiceOrderMapper.pdServiceOrderByBillNumber", deletePd);
        if (pdOrder == null || pdOrder.isEmpty()){
            deletePd.clear();
            return "2";
        }
        String cancelResult = "0", delUserId = deleteUser.getUserId(),delBillNo = pdOrder.getString("so_bill_number"),
        delStatus = String.valueOf(pdOrder.getInt("so_status"));
        //未抢
        if ("0".equals(delStatus)){
            return "3";
        }
        if ("1".equals(delStatus)){//已抢未完成
            return "4";
        }
        if ("4".equals(delStatus)){//抢单人完成，发布人未确认
            return "5";
        }
        StringBuilder deleteSql = new StringBuilder();
        int rows;
        //如果是发布人删除订单
        if (delUserId.equals(pdOrder.getString("so_user_id"))){
            //如果发布人已删除，则直接返回成功
            if ("3".equals(delStatus)){
                return "0";
            }
            //如果是已取消或已过期
            if("5".equals(delStatus) || "6".equals(delStatus)){
                deleteSql.append("insert into cor_delete_order select c.*,now(),null from cor_service_order c WHERE c.so_bill_number='" + delBillNo + "'");
                rows = dao.save("UtilMapper.insertObject", deleteSql.toString());
                if (rows < 1){
                    return "1";
                }
                deleteSql.setLength(0);
                rows = dao.delete("ServiceOrderMapper.deleteOrder", deletePd);
                if (rows < 1){
                    throw new Exception("删除cor_delete_order表的[" + delBillNo + "]订单失败");
                }
                return cancelResult;
            }
            //如果发布人、抢单人都已完成,但抢单人未删除,则修改cor_service_order表的订单状态，
            //并往cor_delete_order表中插入记录
			deleteOrderByPeople(pdOrder,deletePd, delUserId,true);
            deletePd.clear();
            return cancelResult;
        }
		/*--------如果是抢单人删除订单-----------*/
		//如果发布人、抢单人都已完成,但发布人未删除,则修改cor_service_order表的订单状态，
		//并往cor_delete_order表中插入记录
		deleteOrderByPeople(pdOrder,deletePd, delUserId,false);
        return "0";
    }

	/**
	 * 根据发布人或订单人来删除订单
	 * @param pdOrder  要删除的订单
	 * @param deletePd  要删除的参数
	 * @param delUserId  删除的用户ID
	 * @param isIssuer true:发布人删除订单，false:抢单人删除订单
	 * @return  0:成功，1：失败
	 */
    public String deleteOrderByPeople(PageData pdOrder,PageData deletePd, String delUserId,Boolean isIssuer) throws Exception{
		String delStatus = String.valueOf(pdOrder.getInt("so_status")),
				delBillNo = pdOrder.getString("so_bill_number"),
		deletedStatus = isIssuer ? "7" : "3";
    	int rows;
		StringBuilder deleteSql = new StringBuilder();
		if ("2".equals(delStatus)){
			deletePd.put("oldSoStatus", "2");
			deletePd.put(isIssuer ? "noSoGetUser" : "noSoUserId", delUserId);
			deletePd.put(isIssuer ? "soUserId" : "soGetUser", delUserId);
			deletePd.put("soStatus", isIssuer ? "3" : "7");

			//更新状态
			rows = dao.update("ServiceOrderMapper.editServiceOrder", deletePd);
			if (rows < 1){
				return "1";
			}
			String delDate = isIssuer ? "issuer_del_date" : "robber_del_date";
			//存在则更新，不存在则插入
			deleteSql.setLength(0);
			deleteSql.append("INSERT INTO cor_delete_order(so_id,so_bill_number,so_name," + delDate + ") ")
					.append("value(" + pdOrder.getInt("so_id") + ",'" + delBillNo + "','" + pdOrder.getString("so_name") + "',now()) ");
			rows = dao.save("UtilMapper.insertObject", deleteSql.toString());
			if (rows < 1){
				throw new Exception("单号为[" + delBillNo + "]订单插入cor_delete_order表时失败");
			}
		}else if (deletedStatus.equals(delStatus)){
			//如果发布人、抢单人都已完成,且抢单人(或发布人)已删除,则删除cor_service_order表的订单，
			//并修改cor_delete_order表中的订单
			pdOrder.put("so_status",isIssuer ? "3" : "7");
			deleteSql.append("update cor_delete_order set ");
			pdOrder.entrySet().forEach(e -> {
				Map.Entry<String,Object> orderEntry = (Map.Entry)e;
				String eKey = orderEntry.getKey();
				if ("so_id".equals(eKey) || "so_bill_number".equals(eKey) || "so_name".equals(eKey)){
					return;
				}
				deleteSql.append(eKey + "='" + (orderEntry.getValue() == null ? "" : orderEntry.getValue()) + "',");
			});
			deleteSql.append((isIssuer ? "issuer_del_date" : "robber_del_date") + "=now() where so_bill_number='" + delBillNo + "'");
			rows = dao.update("UtilMapper.updateDataBySql", deleteSql.toString());
			if (rows < 1){
				return "1";
			}
			rows = dao.delete("ServiceOrderMapper.deleteOrder", deletePd);
			if (rows < 1){
				throw new Exception((isIssuer ? "发布" : "抢单") + "人删除cor_delete_order表的[" + delBillNo + "]订单失败");
			}
		}
		return "0";
	}
	/**
	 * 发布人完成服务订单操作
	 * @param issuerUserId  发布人用户ID
	 * @param issuerPd  发布人相关参数PageData
	 * @return  0:成功，1：失败
	 */
	public String issuerDoneOrder(String issuerUserId,PageData issuerPd){
		String issueCheckResult = checkDoneOrder(issuerPd,"4","0",issuerUserId);
        if (StringUtils.hasText(issueCheckResult)){
            issuerPd.clear();
            return issueCheckResult;
        }
        issuerPd.put("soUserId", issuerUserId);
        issuerPd.put("oldSoStatus", "4");
        issuerPd.put("noSoGetUser", issuerUserId);
        issuerPd.put("soStatus", "2");
		int rows = dao.update("ServiceOrderMapper.issuerDoneOrder", issuerPd);
        issuerPd.clear();
		return rows > 0 ? "0" : "1";
	}

    /**
     * 获取服务订单集合
     * @param pageData 查询PageData参数
     * @return List<PageData>集合
     */
    public List<PageData> listServiceOrder(PageData pageData) {
        return (List<PageData>) dao.findForList("ServiceOrderMapper.pageMyServiceOrder", pageData);
    }
}